/*
 * flash.c
 *
 *  Created on: Aug 9, 2025
 *      Author: Young
 */
#include "flash.h"

/*
 * globals
 *
 */

uint16_t flashBuffer[BYTE_PRE_PAGE / 2];	//FLASH缓存

/**
 * 读取页
 *
 * @param
 * @return
 */
int readPage(uint16_t pageNumber) {
	// 判断页码是否在范围内
	if (pageNumber >= FLASH_PAGES)
		return -1;
	//
	uint32_t address;
	uint16_t *dataPointer;
	// 首地址
	address = 0x08000000 + pageNumber * BYTE_PRE_PAGE;
	// 读取数据
	for (int i = 0; i < BYTE_PRE_PAGE / 2; i++) {
		dataPointer = (uint16_t*) address + i;
		flashBuffer[i] = *dataPointer;
	}
	return 0;
}

/**
 * 擦除页
 *
 * @param
 * @return
 */
int erasePage(uint16_t pageNumber) {
	// 判断页码是否在范围内
	if (pageNumber >= FLASH_PAGES)
		return -1;
	//
	int result = 0;
	FLASH_EraseInitTypeDef FLASH_EraseInitStruct;
	FLASH_EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
	FLASH_EraseInitStruct.PageAddress = 0x08000000 + pageNumber * BYTE_PRE_PAGE;
	FLASH_EraseInitStruct.NbPages = pageNumber;
	uint32_t pageError = 0;
	// 解锁FLASH
	HAL_FLASH_Unlock();
	// 擦除
	if (HAL_FLASHEx_Erase(&FLASH_EraseInitStruct, &pageError) != HAL_OK) {
		result = -1;
	}
	// 重新上锁
	HAL_FLASH_Lock();
	// return
	return result;
}

/**
 * 写入页
 *
 * @param
 * @return
 */
int writePage(uint16_t pageNumber) {
	// 判断页码是否在范围内
	if (pageNumber >= FLASH_PAGES)
		return -1;
	//
	int result = 0;
	uint32_t address;
	// 解锁FLASH
	HAL_FLASH_Unlock();
	// 循环写入数据
	for (int i = 0; i < BYTE_PRE_PAGE / 2; i++) {
		// 计算写入地址
		address = 0x08000000 + pageNumber * BYTE_PRE_PAGE + i * 2;
		// 写入数据
		if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, address,
				flashBuffer[i]) != HAL_OK) {
			result = -1;
			break;
		}
	}
	//锁定FLASH
	HAL_FLASH_Lock();
	return result;
}

/**
 * 修改FLASH
 *
 * @param
 * @return
 */
int modifyFlash(uint16_t data, uint16_t index) {
	// 读
	if (readPage(60) != 0)
		return -1;
	// 改
	if (index < BYTE_PRE_PAGE / 2) {
		flashBuffer[index] = data;
	} else {
		return -1;
	}
	// 擦
	if (erasePage(60) != 0)
		return -1;
	// 写
	if (writePage(60) != 0)
		return -1;
	return 0;
}
